package com.util.concurrent;

import org.junit.Test;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

public class ConcurrentHashMapDemo {


    /**
     *
     */
    @Test
    public void testPut(){
        Map map = new ConcurrentHashMap();
        String key = null;
        String value = null;
        map.put("", "");

        //concurrentHashMap中key和value都不能为null
        map.put(key, "");//报错
        map.putIfAbsent(key, "");//报错

        map.put("", value);//报错
        map.putIfAbsent("", value);//报错
    }



    /**
     *
     * 当前 Map 中 key 对应的值不存在时，会调用 mappingFunction 函数，并且将该函数的执行结果（不为 null）作为该 key 的 value 返回。
     */
    @Test
    public void computeIfAbsentTest(){
        ConcurrentHashMap map = new ConcurrentHashMap();
        System.out.println("获取key 为 away的值 "+ map.get("away"));

        Function function = (s)-> System.currentTimeMillis();

        map.computeIfAbsent("away", function);
        System.out.println("当away的值为空时设置的值为 "+ map.get("away"));

        map.computeIfAbsent("away", function);
        System.out.println("当away的值存在时不会对原有的值进行改变 "+ map.get("away"));

    }

    /**
     * bug解析 https://mp.weixin.qq.com/s/98yvZ4XkpgmbXtCSUtZVoQ
     * 下面的bug会出现死循环，当两个key的hash值一样时会出现死循环
     */
    @Test
    public void computeIfAbsentBug(){
        Map<String, Integer> map = new ConcurrentHashMap<>(16);
        map.computeIfAbsent(
                "AaAa",
                key -> {
                    return map.computeIfAbsent(
                            "BBBB",
                            key2 -> 42);
                }
        );
    }
}
